package com.skyd.core.android.game;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;

/**
 * 用于存放游戏对象的集合
 * 
 * @author SkyD
 * 
 * @param <T>
 *            GameObject类型
 */
public class GameObjectList<T extends GameObject> implements Iterator<T>,
		Iterable<T> {

	ArrayList<T> _List;

	/**
	 * serialVersionUID
	 */
	private static final long serialVersionUID = -5847464784170298290L;

	/**
	 * 构造函数
	 * 
	 * @param parent
	 *            所属的父对象，该对象将被所有子对象使用
	 */
	public GameObjectList(GameObject parent) {
		_List = new ArrayList<T>();
		setCommonParent(parent);
	}

	/**
	 * 初始值为null。 功能注释：所有子对象共用的父对象
	 */
	private GameObject _CommonParent = null;

	/**
	 * 获取CommonParent。 功能注释：所有子对象共用的父对象
	 * 
	 * @return 当前的GameObject类型的值
	 */
	public GameObject getCommonParent() {
		return _CommonParent;
	}

	/**
	 * 设置CommonParent。 功能注释：所有子对象共用的父对象
	 * 
	 * @param value
	 *            要设置的GameObject类型值
	 */
	public void setCommonParent(GameObject value) {
		_CommonParent = value;
	}

	/**
	 * 设置CommonParent为其默认值(null)。 功能注释：所有子对象共用的父对象
	 */
	public void setCommonParentToDefault() {
		setCommonParent(null);
	}

	public void add(int index, T element) {
		onAddItem(element);
		try {
			element.setParent(getCommonParent());
		} catch (GameException e) {
			e.printStackTrace();
		}
		_List.add(index, element);
		onChanged(_List.size());
	}

	public boolean add(T element) {
		onAddItem(element);
		try {
			element.setParent(getCommonParent());
		} catch (GameException e) {
			e.printStackTrace();
		}
		boolean b = _List.add(element);
		onChanged(_List.size());
		return b;
	}

	public boolean addAll(Collection<? extends T> c) {
		for (T f : c) {
			onAddItem(f);
			try {
				f.setParent(getCommonParent());
			} catch (GameException e) {
				e.printStackTrace();
			}
		}
		boolean b = _List.addAll(c);
		onChanged(_List.size());
		return b;
	}

	public boolean addAll(int index, Collection<? extends T> c) {
		for (T f : c) {
			onAddItem(f);
			try {
				f.setParent(getCommonParent());
			} catch (GameException e) {
				e.printStackTrace();
			}
		}
		boolean b = _List.addAll(index, c);
		onChanged(_List.size());
		return b;
	}

	public T get(int index) {
		return _List.get(index);
	}

	public T remove(int index) {
		onRemoveItem(get(index));
//		try {
//			get(index).setParentToDefault();
//		} catch (GameException e) {
//			e.printStackTrace();
//		}
		T r = _List.remove(index);
		onChanged(_List.size());
		return r;
	}

	public boolean remove(T o) {
		onRemoveItem(o);
//		try {
//			o.setParentToDefault();
//		} catch (GameException e) {
//			e.printStackTrace();
//		}
		boolean b = _List.remove(o);
		onChanged(_List.size());
		return b;
	}

	public T set(int index, T element) {
		onRemoveItem(get(index));
		onAddItem(element);
		try {
			get(index).setParentToDefault();
			element.setParent(getCommonParent());
		} catch (GameException e) {
			e.printStackTrace();
		}
		T r = _List.set(index, element);
		onChanged(_List.size());
		return r;
	}

	public boolean removeAll(Collection<T> c) {
		for (T f : c) {
			onRemoveItem(f);
//			try {
//				f.setParentToDefault();
//			} catch (GameException e) {
//				e.printStackTrace();
//			}
		}
		boolean b = _List.removeAll(c);
		onChanged(_List.size());
		return b;
	}

	public boolean retainAll(Collection<T> c) {
		for (T f : _List) {
			if (!c.contains(f)) {
				onRemoveItem(f);
//				try {
//					f.setParentToDefault();
//				} catch (GameException e) {
//					e.printStackTrace();
//				}
			}
		}
		boolean b = _List.retainAll(c);
		onChanged(_List.size());
		return b;
	}

	/**
	 * 当集合改变后触发
	 */
	public interface OnChangedListener {
		/**
		 * 触发Changed事件时执行的方法。事件功能注释：当集合改变后触发
		 * 
		 * @param sender
		 *            触发Changed事件的对象
		 */
		public abstract void OnChangedEvent(Object sender, int newSize);
	}

	/**
	 * Changed事件监听器列表。当集合改变后触发
	 */
	private ArrayList<OnChangedListener> _ChangedListenerList = null;

	/**
	 * 增加一个Changed事件的监听器，返回是否成功增加。事件功能注释：当集合改变后触发
	 * 
	 * @param listener
	 *            Changed事件监听器对象
	 * @return 是否成功增加。如果该监听器对象已存在，则返回false。
	 */
	public boolean addOnChangedListener(OnChangedListener listener) {
		if (_ChangedListenerList == null)
			_ChangedListenerList = new ArrayList<OnChangedListener>();
		else if (_ChangedListenerList.contains(listener))
			return false;
		_ChangedListenerList.add(listener);
		return true;
	}

	/**
	 * 移除一个Changed事件的监听器，返回是否成移除。事件功能注释：当集合改变后触发
	 * 
	 * @param listener
	 *            Changed事件监听器对象
	 * @return 是否成功移除。如果该监听器对象不存在，则返回false。
	 */
	public boolean removeOnChangedListener(OnChangedListener listener) {
		if (_ChangedListenerList == null
				|| !_ChangedListenerList.contains(listener))
			return false;
		_ChangedListenerList.remove(listener);
		return true;
	}

	/**
	 * 清空所有Changed事件的监听器。事件功能注释：当集合改变后触发
	 */
	public void clearOnChangedListeners() {
		if (_ChangedListenerList != null)
			_ChangedListenerList.clear();
	}

	/**
	 * 当集合改变后触发
	 */
	protected void onChanged(int newSize) {
		if (_ChangedListenerList != null)
			for (OnChangedListener listener : _ChangedListenerList) {
				listener.OnChangedEvent(this, newSize);
			}
	}

	/**
	 * 添加子项时触发
	 */
	public interface OnAddItemListener<T> {
		/**
		 * 触发AddItem事件时执行的方法。事件功能注释：添加子项时触发
		 * 
		 * @param sender
		 *            触发AddItem事件的对象
		 */
		public abstract void OnAddItemEvent(Object sender, T newItem);
	}

	/**
	 * AddItem事件监听器列表。添加子项时触发
	 */
	private ArrayList<OnAddItemListener<T>> _AddItemListenerList = null;

	/**
	 * 增加一个AddItem事件的监听器，返回是否成功增加。事件功能注释：添加子项时触发
	 * 
	 * @param listener
	 *            AddItem事件监听器对象
	 * @return 是否成功增加。如果该监听器对象已存在，则返回false。
	 */
	public boolean addOnAddItemListener(OnAddItemListener<T> listener) {
		if (_AddItemListenerList == null)
			_AddItemListenerList = new ArrayList<OnAddItemListener<T>>();
		else if (_AddItemListenerList.contains(listener))
			return false;
		_AddItemListenerList.add(listener);
		return true;
	}

	/**
	 * 移除一个AddItem事件的监听器，返回是否成移除。事件功能注释：添加子项时触发
	 * 
	 * @param listener
	 *            AddItem事件监听器对象
	 * @return 是否成功移除。如果该监听器对象不存在，则返回false。
	 */
	public boolean removeOnAddItemListener(OnAddItemListener<T> listener) {
		if (_AddItemListenerList == null
				|| !_AddItemListenerList.contains(listener))
			return false;
		_AddItemListenerList.remove(listener);
		return true;
	}

	/**
	 * 清空所有AddItem事件的监听器。事件功能注释：添加子项时触发
	 */
	public void clearOnAddItemListeners() {
		if (_AddItemListenerList != null)
			_AddItemListenerList.clear();
	}

	/**
	 * 添加子项时触发
	 */
	protected void onAddItem(T newItem) {
		if (_AddItemListenerList != null)
			for (OnAddItemListener<T> listener : _AddItemListenerList) {
				listener.OnAddItemEvent(this, newItem);
			}
	}

	/**
	 * 移除子项时触发
	 */
	public interface OnRemoveItemListener<T> {
		/**
		 * 触发RemoveItem事件时执行的方法。事件功能注释：移除子项时触发
		 * 
		 * @param sender
		 *            触发RemoveItem事件的对象
		 */
		public abstract void OnRemoveItemEvent(Object sender, T oldItem);
	}

	/**
	 * RemoveItem事件监听器列表。移除子项时触发
	 */
	private ArrayList<OnRemoveItemListener<T>> _RemoveItemListenerList = null;

	/**
	 * 增加一个RemoveItem事件的监听器，返回是否成功增加。事件功能注释：移除子项时触发
	 * 
	 * @param listener
	 *            RemoveItem事件监听器对象
	 * @return 是否成功增加。如果该监听器对象已存在，则返回false。
	 */
	public boolean addOnRemoveItemListener(OnRemoveItemListener<T> listener) {
		if (_RemoveItemListenerList == null)
			_RemoveItemListenerList = new ArrayList<OnRemoveItemListener<T>>();
		else if (_RemoveItemListenerList.contains(listener))
			return false;
		_RemoveItemListenerList.add(listener);
		return true;
	}

	/**
	 * 移除一个RemoveItem事件的监听器，返回是否成移除。事件功能注释：移除子项时触发
	 * 
	 * @param listener
	 *            RemoveItem事件监听器对象
	 * @return 是否成功移除。如果该监听器对象不存在，则返回false。
	 */
	public boolean removeOnRemoveItemListener(OnRemoveItemListener<T> listener) {
		if (_RemoveItemListenerList == null
				|| !_RemoveItemListenerList.contains(listener))
			return false;
		_RemoveItemListenerList.remove(listener);
		return true;
	}

	/**
	 * 清空所有RemoveItem事件的监听器。事件功能注释：移除子项时触发
	 */
	public void clearOnRemoveItemListeners() {
		if (_RemoveItemListenerList != null)
			_RemoveItemListenerList.clear();
	}

	/**
	 * 移除子项时触发
	 */
	protected void onRemoveItem(T oldItem) {
		if (_RemoveItemListenerList != null)
			for (OnRemoveItemListener<T> listener : _RemoveItemListenerList) {
				listener.OnRemoveItemEvent(this, oldItem);
			}
	}

	@Override
	public boolean hasNext() {
		return _List.iterator().hasNext();
	}

	@Override
	public T next() {
		return _List.iterator().next();
	}

	@Override
	public void remove() {
		_List.iterator().remove();
	}

	@SuppressWarnings("unchecked")
	@Override
	public Iterator<T> iterator() {
		_MIRROR = (ArrayList<T>) _List.clone();
		return _MIRROR.iterator();
	}

	ArrayList<T> _MIRROR;

	public void sort(Comparator<T> c) {
		Collections.sort(_List, c);
	}

	public int size() {
		return _List.size();
	}
}
